<cfcomponent name="ManagerBase" output="false">

	<cfproperty name="factory" type="any" />
	<cfproperty name="pageManager" type="any" />
	<cfset variables.instance = {} />
	
	
	<!--- init() --->
	<cffunction name="init" access="public" output="no" returntype="any">
		<cfargument name="factory" type="any" required="yes" />
		<cfargument name="pageManager" type="any" required="yes" />
		<cfscript>
			setFactory(arguments.factory);
			setPageManager(arguments.pageManager);
			return this;
		</cfscript>
	</cffunction>
	
	
	<!--- add() --->
	<cffunction name="add" access="public" output="false">
		<cfscript>
			var local = {};
			
			// Transform the action key into a valid TRG (type, region, group) key
			local.trgKey = getPageManager().actionKeyToTRGKey(original=arguments.actionKey, attributes=arguments);
			
			// Attempt to retrieve data from the cache with the TRG key
			local.cachedData = getPageManager().getFromCache(key=local.trgKey);
			if (NOT IsDefined("local.cachedData")) {
				// Cached data was not found with the TRG key, so we need to actually generate the output
				getFactory().add(argumentCollection=arguments);	
			}
			else {
				getPageManager().saveToCache(
					getFactory().buildRequestKey(argumentCollection=arguments),
					local.cachedData
				);
			}
		</cfscript>
	</cffunction>

	
	<!--- combine() --->
	<cffunction name="combine" access="public" output="false">
		<cfscript>
			var local = {};
			
			// Transform the action key into a valid TRG (type, region, group) key
			local.trgKey = getPageManager().actionKeyToTRGKey(original=arguments.actionKey, attributes=arguments);
			local.comboKey = getPageManager().trgKeyToComboKey(local.trgKey);
			
			// Attempt to retrieve data from the cache with the TRG key
			local.cachedData = getPageManager().getFromCache(key=local.comboKey);
			if (NOT IsDefined("local.cachedData")) {
				// Cached data was not found with the TRG key, so we need to actually generate the output
				getFactory().combine(argumentCollection=arguments);	
			}
			else {
				getPageManager().saveToCache(
					getFactory().buildRequestKey(argumentCollection=arguments),
					local.cachedData
				);
			}
		</cfscript>
	</cffunction>
	
	
	<!--- save() --->
	<cffunction name="save" access="public" output="false">
		<cfscript>
			var local = {};
			
			// Transform the action key into a valid TRG (type, region, group) key
			local.trgKey = getPageManager().actionKeyToTRGKey(original=arguments.actionKey, attributes=arguments);
			local.comboKey = getPageManager().trgKeyToComboKey(local.trgKey);
			
			// Generate the output
			local.outputResult = getFactory().output(request=arguments.request, type=arguments.type, region=arguments.region, group=arguments.group);
			
			// Save the output to cache using the TRG key
			getPageManager().saveToCache(
				local.trgKey,
				local.outputResult
			);
			
			// If this group has been combined the save statement SHOULD mention it.
			// If so, we need to make a new cache item for the combined output
			if (StructKeyExists(arguments, "combined") AND (arguments.combined)) {
				getPageManager().saveToCache(
					local.comboKey,
					local.outputResult
				);
			}
			
			// Create the request-specific item
			getPageManager().saveToCache(
				getFactory().buildRequestKey(argumentCollection=arguments),
				local.outputResult
			);
		</cfscript>
	</cffunction>	
	
	
	<!--- buildActionKey() --->
	<cffunction name="buildActionKey" access="private" returntype="string">
		<cfargument name="action" type="string" required="yes" />
		<cfargument name="args" type="struct" required="no" />
		<cfargument name="argList" type="string" required="no" default="" />
		<cfscript>
			var local = {};
			local.actionKey = "sw3_action:#arguments.action#";
			for (local.key in arguments.args) {
				if (ListFindNoCase(arguments.argList, local.key)) {
					local.actionKey &= "_#local.key#:#arguments.args[local.key]#";
				}
			}
			return LCase(local.actionKey);
		</cfscript>
	</cffunction>
	
	
	<!--- setFactory() --->
	<cffunction name="setFactory" access="private" output="false" returntype="void">
		<cfargument name="factory" type="any" required="true" />
		<cfset variables.instance["factory"] = arguments.factory />
	</cffunction>
	
	
	<!--- getFactory() --->
	<cffunction name="getFactory" access="private" output="false" returntype="any">
		<cfreturn variables.instance["factory"] />
	</cffunction>
	
	
	<!--- setPageManager() --->
	<cffunction name="setPageManager" access="private" output="false" returntype="void">
		<cfargument name="manager" type="any" required="true" />
		<cfset variables.instance["pageManager"] = arguments.manager />
	</cffunction>
	
	
	<!--- getPageManager() --->
	<cffunction name="getPageManager" access="private" output="false" returntype="any">
		<cfreturn variables.instance["pageManager"] />
	</cffunction>
	
	
</cfcomponent>